/*
就像在golang中，if err != nil {}和if someData != nil {}无处不在一样，在Rust中，Option和Result也是随处可见；
Option和Result都是enum，如果都用match来进行判断的话，代码的递进深度会比较深，另外代码也看起来会很冗余。
为此Rust为Option和Result提供了很多便利的操作。
 */
use std::io::{self, Error};

#[test]
fn main(){
    let r1 = test01();
    println!("r1 is_ok={}, is_err={}", r1.is_ok(), r1.is_err());

    let r2 = test02();
    println!("r2 is_ok={}, res={}", r2.is_ok(), r2.unwrap());

    let r31 = test03(1);
    println!("r31 is_ok={}, res={}", r31.is_ok(), r31.unwrap());

    let r32 = test03(2);
    println!("r32 is_ok={}, res={}", r32.is_ok(), r32.unwrap());

    // 使用unwrap_err提取错误信息。
    let r33 = test03(3);
    println!("r33 is_ok={}, res={}", r33.is_ok(), r33.unwrap_err());

    let r4 = test04();
    println!("r4 is_ok={}, res={:?}", r4.is_ok(), r4);
}

/*
只返回结果状态，不返回数据
 */
fn test01() -> io::Result<()>{
    Ok(())
}

/*
返回结果状态，也返回数据
 */
fn test02() -> io::Result<String>{
    Ok(String::from("test02 is ok"))
}

/*
返回结果状态，也返回数据
 */
fn test03(num: i32) -> Result<i32, String> {
    match num {
        1 => Ok(11),
        2 => Ok(22),
        _ => Err("必须是1或2".to_string())
    }
}

fn test04() -> Result<[i32; 3], String>{
    Ok([1, 2, 3])
}